<?php


namespace app\api\controller;

use app\common\model\User;
use app\common\model\Order;
use app\common\model\ShopConfig;
use app\common\model\UserLevelPay;
use app\common\model\RechargeOrder;
use app\common\model\CurriculumOrder;
use app\api\logic\PayLogic;
use Exception;
use think\Request;
use think\response\Json;
use tools\Crypt;
use tools\PayApi;
use tools\AesUtil;
use think\facade\Log;
use think\facade\Hook;
use think\Db;

class PaymentController extends ApiBase
{
    protected $authExcept = [
        'wxnotify'
    ];


    /**
     * Notes:支付方式
     * @return \think\Model[]
     */
    public function payway()
    {
        $params = $this->request->get();
        if(!isset($params['from']) || !isset($params['order_sn'])) {
            return error('参数缺失');
        }
        if($params['from'] == 'order') {
            $order = Db::name('order')->where('order_sn', $params['order_sn'])->find();
        }else if($params['from'] == 'recharge') {
            $order = Db::name('recharge_order')->where('order_sn', $params['order_sn'])->find();
        }else if($params['from'] == 'vip') {
            $order = Db::name('user_level_pay')->where('order_sn', $params['order_sn'])->field('money as order_amount,create_time')->find();
        }else if($params['from'] == 'curriculum') {
            $order = Db::name('curriculum_order')->where('order_sn', $params['order_sn'])->field('order_amount,create_time')->find();
        }
        // 订单自动取消时间
        $cancelTime =30; //ShopConfig::get('trading', 'order_cancel');
        if(empty($cancelTime)) {
            // 前端检测为0时不显示倒计时
            $cancelTime = 0;
        }else{
            // 订单创建时间 + 后台设置自动关闭未付款订单时长
            $cancelTime = $order['create_time'] + intval($cancelTime) * 60;
        }
        $data = [
            'order_amount' => $order['order_amount'],
            'cancel_time' => $cancelTime,
        ];
        return success($data);
    }

    /**
     * Notes: 预支付
     */
    public function prepay(Request $request)
    {
        $param = $request->param();
        if($this->uid==0){
            return unauthorized('请先授权');
        }
        $user_id=$this->uid;
        $order_sn=$param['order_sn']??'';
        if(!$order_sn) {
            return error('订单不存在');
        }
        $pay_way=$param['pay_way']??'';
        if(!$pay_way) {
            return error('支付方式不存在');
        }
        switch ($param['from']) {
            case 'vip':
                $omodel= new UserLevelPay();
                $order = $omodel
                    ->alias('o')
                    ->field("o.order_status,o.money as order_amount,o.order_sn,user_id,o.id as order_id,o.user_num,o.user_vip_id")
                    ->where(array('o.order_sn'=>$order_sn,'o.user_id'=>$user_id))
                    ->find();
                $body='购买会员'.$order['order_sn'];
                //找不到订单
                if (empty($order)) {
                    return error('订单不存在');
                }
                if ($order['order_status'] !='10') {
                    return error('该订单无法进行支付，请查看订单状态');
                }
                Db::name('user_level_pay')->where('id', $order['order_id'])->update(['pay_way' => $pay_way]);
                break;
            case 'order':
                $omodel= new Order();
                $order = $omodel
                    ->alias('o')
                    ->field("o.order_status,o.order_amount,o.order_sn,o.id as order_id,o.user_id")
                    ->where(array('o.order_sn'=>$order_sn,'o.user_id'=>$user_id))
                    ->find();
                $body='商品订单'.$order['order_sn'];
                if($order['order_status']==0){
                    $order['order_status']=10;
                }
                if (empty($order)) {
                    return error('订单不存在');
                }
                if ($order['order_status'] !='10') {
                    return error('该订单无法进行支付，请查看订单状态');
                }
                Db::name('order')->where('id', $order['order_id'])->update(['pay_way' => $pay_way]);
                break;
            case 'recharge':
                $order = Db::name('recharge_order')
                    ->alias('o')
                    ->field("o.pay_status,o.order_amount,o.order_sn,o.id as order_id,o.user_id,o.give_money")
                    ->where(array('o.order_sn'=>$order_sn,'o.user_id'=>$user_id))
                    ->find();
                $body='充值订单'.$order['order_sn'];
                //找不到订单
                if (empty($order)) {
                    return error('订单不存在');
                }
                if ($order['pay_status'] !='0') {
                    return error('无法进行支付，请查看订单状态');
                }
                Db::name('recharge_order')->where('id', $order['order_id'])->update(['pay_way' => $pay_way]);
                break;
            case 'curriculum':
                $order = Db::name('curriculum_order')
                    ->alias('o')
                    ->field("o.order_status,o.order_amount,o.order_sn,o.id as order_id,o.user_id")
                    ->where(array('o.order_sn'=>$order_sn,'o.user_id'=>$user_id))
                    ->find();
                $body='课程订单'.$order['order_sn'];
                if($order['order_status']==0){
                    $order['order_status']=10;
                }
                if (empty($order)) {
                    return error('订单不存在');
                }
                if ($order['order_status'] !='10') {
                    return error('该订单无法进行支付，请查看订单状态');
                }
                Db::name('curriculum_order')->where('id', $order['order_id'])->update(['pay_way' => $pay_way]);
                break;
        }
        $wxData='';
        switch ($pay_way) {
            case 1:
                $where[] = ['user_id', '=', $user_id];
                $where[] = ['client', '=',1];
                $auth = Db::name('user_auth')->where($where)->find();
                if(!$auth){
                    return error('用户授权参数不足，请重新登录');
                }
                $order_wechatsn =$order['order_sn'].str_pad(mt_rand(1, 999), 3, '0', STR_PAD_LEFT);
                $PayApi=new PayApi();
                $wxData=$PayApi->preWxPay('jsapi',$body,$order_wechatsn,$order['order_amount'],$auth['openid']);
                break;
            case 2:
                $user = User::get($order['user_id']);
                if ($user['earnings'] < $order['order_amount']) {
                    return error('佣金不足');
                }
                if($param['from']=='recharge'){
                    PayLogic::Recharge_pay($order,['pay_way'=>2]);
                }
                break;
            case 3:
                $user = User::get($order['user_id']);
                if ($user['user_money'] < $order['order_amount']) {
                    return error('余额不足');
                }
                if($param['from']=='vip'){
                    PayLogic::UserLevel_pay($order,['pay_way'=>3]);
                }
                if($param['from']=='order'){
                    PayLogic::Order_pay($order,['pay_way'=>3]);
                }
                if($param['from']=='recharge'){
                    PayLogic::Recharge_pay($order,['pay_way'=>3]);
                }
                if($param['from']=='curriculum'){
                    PayLogic::CurriculumOrder_pay($order,['pay_way'=>3]);
                }
                break;
        }
        return success($wxData);
    }

    //微信回调
    public function wxnotify(Request $request)
    {
        $param = $request->param();
        $mch_v3_key = config('wechat.wechat_xiaochengxu.mch_v3_key');
        $AesUtil=new AesUtil($mch_v3_key);
        $pay_notify=$AesUtil->decryptToString($param['resource']['associated_data'],$param['resource']['nonce'],$param['resource']['ciphertext']);
        $data=json_decode($pay_notify, true);
        Log::write('微信回调2：'.var_export($data, true));
        if($data['trade_state']==='SUCCESS'){
            $order_sn_a=mb_substr($data['out_trade_no'],0,1);//获取订单第一个字符
            //购买会员
            if($order_sn_a=='Q'){
                $order_sn = mb_substr($data['out_trade_no'],0,19);
                $omodel= new UserLevelPay();
                $order_info = $omodel
                    ->alias('o')
                    ->field("o.order_status,o.money as order_amount,o.order_sn,user_id,o.id as order_id,o.user_num,o.user_vip_id")
                    ->where(array('o.order_sn'=>$order_sn))
                    ->find();
            } 
            if($order_sn_a=='O'){
                $order_sn = mb_substr($data['out_trade_no'],0,19);
                $omodel= new Order();
                $order_info = $omodel
                    ->alias('o')
                    ->field("o.order_status,o.order_amount,o.order_sn,user_id,o.id as order_id,o.order_type")
                    ->where(array('o.order_sn'=>$order_sn))
                    ->find();
            } 
            //充值
            if($order_sn_a=='C'){
                $order_sn = mb_substr($data['out_trade_no'],0,19);
                $omodel= new RechargeOrder();
                $order_info = $omodel
                    ->alias('o')
                    ->field("o.pay_status,o.order_amount,o.order_sn,o.id as order_id,o.user_id,o.give_money")
                    ->where(array('o.order_sn'=>$order_sn))
                    ->find();
            }
            if($order_sn_a=='K'){
                $order_sn = mb_substr($data['out_trade_no'],0,19);
                $omodel= new CurriculumOrder();
                $order_info = $omodel
                    ->alias('o')
                    ->field("o.order_status,o.order_amount,o.order_sn,user_id,o.id as order_id,o.order_type")
                    ->where(array('o.order_sn'=>$order_sn))
                    ->find();
            } 
            if($order_info){
                // 启动事务
                $omodel->startTrans();
                try {
                    if($order_sn_a=='Q'){
                        PayLogic::UserLevel_pay($order_info,['transaction_id'=>$data['transaction_id']]);
                    }
                    if($order_sn_a=='O'){
                        PayLogic::Order_pay($order_info,['transaction_id'=>$data['transaction_id']]);
                    }
                    if($order_sn_a=='C'){
                        PayLogic::Recharge_pay($order_info,['transaction_id'=>$data['transaction_id']]);
                    }
                    if($order_sn_a=='K'){
                        PayLogic::CurriculumOrder_pay($order_info,['transaction_id'=>$data['transaction_id']]);
                    }
                    $omodel->commit();
                } catch (Exception $e) {
                    $omodel->rollback();
                    Log::write('微信回调666：'.var_export($e->getMessage(), true));
                    exit('fail');
                }
                exit('success');
            }
        }
        exit('fail');
    }

    /**
     * 将xml转为array
     * @param  string $xml xml字符串
     * @return array       转换得到的数组
     */
    public function toArray($xml) {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }
}